package com.bytedance.speech.speechdemo;

import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.ProcessLifecycleOwner;

import android.Manifest;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.bytedance.speech.speechdemo.settings.Settings;
import com.bytedance.speech.speechdemo.utils.SensitiveDefines;
import com.bytedance.speech.speechdemo.utils.SpeechDemoDefines;
import com.bytedance.speech.speechengine.SpeechEngine;
import com.bytedance.speech.speechengine.SpeechEngineDefines;
import com.bytedance.speech.speechengine.SpeechEngineGenerator;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.Collections;
import java.util.List;

public class DialogActivity extends BaseActivity implements SpeechEngine.SpeechListener, LifecycleObserver {

    // UI
    private Button mInitEngineBtn;
    private Button mUninitEngineBtn;
    private Button mStartEngineBtn;
    private Button mStopEngineBtn;
    private Button mStartDialogBtn;
    private Button mStopDialogBtn;
    private Button mRecordBtn;
    private TextView mEngineStatusTv;
    private TextView mResultTv;

    // Record
    private Handler recordHandler = null;
    private Runnable recordRunnable = null;
    private boolean recordIsRunning = false;

    // Settings
    protected Settings mSettings;

    // Paths
    private String mDebugPath = "";

    // Engine
    private SpeechEngine mSpeechEngine = null;
    private boolean mEngineStarted = false;

    // Permissions
    private static final List<String> DIALOG_PERMISSIONS = Collections.singletonList(
            Manifest.permission.RECORD_AUDIO
    );

    @SuppressLint({"ClickableViewAccessibility", "InflateParams", "HardwareIds", "UseCompatLoadingForDrawables"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i(SpeechDemoDefines.TAG, "Dialog onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog);
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);

        setTitleBar(R.string.dialog_name);
        String viewId = SpeechDemoDefines.DIALOG_VIEW;
        mSettings = SettingsActivity.getSettings(viewId);

        Button mConfig = findViewById(R.id.engine_config);
        mConfig.setEnabled(true);
        mConfig.setOnClickListener(v -> goToSettingsActivity(viewId));

        mInitEngineBtn = findViewById(R.id.init_engine_button);
        setButton(mInitEngineBtn, true);
        mInitEngineBtn.setOnClickListener(v -> initEngineBtnClicked());

        mUninitEngineBtn = findViewById(R.id.uninit_engine_button);
        setButton(mUninitEngineBtn, false);
        mUninitEngineBtn.setOnClickListener(v -> uninitEngineBtnClicked());

        mStartEngineBtn = findViewById(R.id.start_engin_button);
        setButton(mStartEngineBtn, false);
        mStartEngineBtn.setOnClickListener(v -> startEngineBtnClicked());

        mStopEngineBtn = findViewById(R.id.stop_button);
        setButton(mStopEngineBtn, false);
        mStopEngineBtn.setOnClickListener(v -> stopEngineBtnClicked());

        mStartDialogBtn = findViewById(R.id.start_dialog_button);
        setButton(mStartDialogBtn, false);
        mStartDialogBtn.setOnClickListener(v -> startDialogBtnClicked());

        mStopDialogBtn = findViewById(R.id.stop_dialog_button);
        setButton(mStopDialogBtn, false);
        mStopDialogBtn.setOnClickListener(v -> stopDialogBtnClicked());

        mRecordBtn = findViewById(R.id.long_press);
        setButton(mRecordBtn, false);

        mRecordBtn.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                Log.i(SpeechDemoDefines.TAG, "Record: Action down");
                mRecordBtn.setBackground(getResources().getDrawable(R.drawable.btn_negative_background));
                recordBtnTouchDown();
                return true;
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                Log.i(SpeechDemoDefines.TAG, "Record: Action up");
                mRecordBtn.setBackground(getResources().getDrawable(R.drawable.btn_active_background));
                recordBtnTouchUp();
                return true;
            } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                Log.i(SpeechDemoDefines.TAG, "Record: Action cancel");
                mRecordBtn.setBackground(getResources().getDrawable(R.drawable.btn_active_background));
                recordBtnTouchUp();
                return true;
            }
            return false;
        });

        mResultTv = findViewById(R.id.result_text);
        mResultTv.setMovementMethod(new ScrollingMovementMethod());

        mEngineStatusTv = findViewById(R.id.engine_status);
        mEngineStatusTv.setText(R.string.hint_waiting_init);
    }

    @Override
    protected void onDestroy() {
        Log.i(SpeechDemoDefines.TAG, "Dialog onDestroy");
        uninitEngine();
        super.onDestroy();
    }

    private void configInitParams() {
        //【必需配置】Engine Name
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_ENGINE_NAME_STRING, SpeechEngineDefines.DIALOG_ENGINE);

        //【可选配置】Debug & Log
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DEBUG_PATH_STRING, mDebugPath);
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_LOG_LEVEL_STRING, SpeechEngineDefines.LOG_LEVEL_TRACE);

        String appid = mSettings.getString(R.string.config_app_id);
        if (appid.isEmpty()) {
            appid = SensitiveDefines.APPID;
        }
        //【必需配置】Authentication：Appid
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_APP_ID_STRING, appid);

        String token = mSettings.getString(R.string.config_token);
        if (token.isEmpty()) {
            token = SensitiveDefines.TOKEN;
        }
        //【必需配置】Authentication：Token
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_APP_TOKEN_STRING, token);

        //【必需配置】User ID（用以辅助定位线上用户问题，如无法提供可提供固定字符串）
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_UID_STRING, SensitiveDefines.UID);

        //【必需配置】Dialog App ID
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_APP_ID_STRING, SensitiveDefines.DIALOG_DEFAULT_APP_ID);

        String address = mSettings.getString(R.string.config_address);
        if (address.isEmpty()) {
            address = SensitiveDefines.DEFAULT_ADDRESS;
        }
        Log.i(SpeechDemoDefines.TAG, "Current address: " + address);
        //【必需配置】Dialog Address，对话服务域名
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_ADDRESS_STRING, address);

        String uri = mSettings.getString(R.string.config_uri);
        if (uri.isEmpty()) {
            uri = SensitiveDefines.DIALOG_DEFAULT_URI;
        }
        Log.i(SpeechDemoDefines.TAG, "Current uri: " + uri);
        //【必需配置】Dialog Uri，对话服务Uri
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_URI_STRING, uri);
    }

    private void configStartDialogParams() {
        String dialogId = mSettings.getString(R.string.config_dialog_id);
        if (dialogId.isEmpty()) {
            dialogId = SensitiveDefines.DIALOG_DEFAULT_ID;
        }
        Log.i(SpeechDemoDefines.TAG, "Current dialog id: " + dialogId);
        //【必需配置】Dialog id，对话剧本ID
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_ID_STRING, dialogId);

        String dialogRole = mSettings.getString(R.string.config_dialog_role);
        if (dialogRole.isEmpty()) {
            dialogRole = SensitiveDefines.DIALOG_DEFAULT_ROLE;
        }
        Log.i(SpeechDemoDefines.TAG, "Current dialog role: " + dialogRole);
        //【必需配置】Dialog role，对话数字人角色
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_ROLE_STRING, dialogRole);

        String dialogClothesType = mSettings.getString(R.string.config_dialog_clothes_type);
        if (dialogClothesType.isEmpty()) {
            dialogClothesType = SensitiveDefines.DIALOG_DEFAULT_CLOTHES_TYPE;
        }
        Log.i(SpeechDemoDefines.TAG, "Current dialog clothes type: " + dialogClothesType);
        //【必需配置】Dialog clothes type，对话数字人服饰类型
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_CLOTHES_TYPE_STRING, dialogClothesType);

        String dialogTtaVoiceType = mSettings.getString(R.string.config_dialog_tta_voice_type);
        if (dialogTtaVoiceType.isEmpty()) {
            dialogTtaVoiceType = SensitiveDefines.DIALOG_DEFAULT_TTA_VOICE_TYPE;
        }
        Log.i(SpeechDemoDefines.TAG, "Current dialog tta voice type: " + dialogTtaVoiceType);
        //【必需配置】Dialog tta voice type，对话数字人音色
        mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_TTA_VOICE_TYPE_STRING, dialogTtaVoiceType);
    }

    private void initEngine() {
        if (mDebugPath.isEmpty()) {
            mDebugPath = getDebugPath();
        }
        Log.i(SpeechDemoDefines.TAG, "Debug path:" + mDebugPath);

        if (mSpeechEngine == null) {
            Log.i(SpeechDemoDefines.TAG, "创建引擎.");
            mSpeechEngine = SpeechEngineGenerator.getInstance();
            mSpeechEngine.createEngine();
            mSpeechEngine.setContext(getApplicationContext());
        }
        Log.i(SpeechDemoDefines.TAG, "SDK version: " + mSpeechEngine.getVersion());

        Log.i(SpeechDemoDefines.TAG, "配置初始化参数.");
        configInitParams();

        Log.i(SpeechDemoDefines.TAG, "引擎初始化.");
        int ret = mSpeechEngine.initEngine();
        if (ret != SpeechEngineDefines.ERR_NO_ERROR) {
            String errMessage = "Init Engine Faile: " + ret;
            speechEngineInitFailed(errMessage);
            return;
        }

        Log.i(SpeechDemoDefines.TAG, "设置监听.");
        mSpeechEngine.setListener(this);

        // 设置RemoteView，用来展示视频流
        this.runOnUiThread(() -> {
            FrameLayout frameLayout = findViewById(R.id.remote_view_fl);
            if (frameLayout != null) {
                frameLayout.removeAllViews();
                SurfaceView surfaceView = new SurfaceView(getApplicationContext());
                frameLayout.addView(surfaceView,
                        new FrameLayout.LayoutParams(
                                ViewGroup.LayoutParams.MATCH_PARENT,
                                ViewGroup.LayoutParams.MATCH_PARENT));
                Log.i(SpeechDemoDefines.TAG, "设置RemoteView.");
                mSpeechEngine.setRemoteView(surfaceView);
            }
        });

        speechEnginInitOk();
    }

    private void uninitEngine() {
        if (mSpeechEngine != null) {
            Log.i(SpeechDemoDefines.TAG, "引擎析构.");
            mSpeechEngine.destroyEngine();
            mSpeechEngine = null;
            Log.i(SpeechDemoDefines.TAG, "引擎析构完成!");
        }
    }

    private void initEngineBtnClicked() {
        if (mEngineStarted) {
            mEngineStatusTv.setText(R.string.hint_engine_busy);
            return;
        }
        setButton(mStartEngineBtn, false);
        setButton(mStopEngineBtn, false);
        setButton(mStartDialogBtn, false);
        setButton(mStopDialogBtn, false);
        setButton(mRecordBtn, false);
        initEngine();
    }

    private void uninitEngineBtnClicked() {
        if (mEngineStarted) {
            mEngineStatusTv.setText(R.string.hint_engine_busy);
            return;
        }
        uninitEngine();
        mEngineStatusTv.setText(R.string.hint_waiting_init);
        mResultTv.setText("");

        setButton(mInitEngineBtn, true);
        setButton(mUninitEngineBtn, false);
        setButton(mStartEngineBtn, false);
        setButton(mStopEngineBtn, false);
        setButton(mStartDialogBtn, false);
        setButton(mStopDialogBtn, false);
    }

    private void startEngineBtnClicked() {
        // Directive：启动引擎前调用SYNC_STOP指令，保证前一次请求结束。
        Log.i(SpeechDemoDefines.TAG, "Directive: DIRECTIVE_SYNC_STOP_ENGINE");
        int ret = mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_SYNC_STOP_ENGINE, "");
        if (ret != SpeechEngineDefines.ERR_NO_ERROR) {
            Log.e(SpeechDemoDefines.TAG, "send directive syncstop failed, " + ret);
        } else {
            // Directive：启动引擎指令。
            Log.i(SpeechDemoDefines.TAG, "Directive: DIRECTIVE_START_ENGINE");
            ret = mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_START_ENGINE, "");
            if (ret == SpeechEngineDefines.ERR_REC_CHECK_ENVIRONMENT_FAILED) {
                mEngineStatusTv.setText(R.string.check_rec_permission);
                requestPermission(DIALOG_PERMISSIONS);
            } else if (ret != SpeechEngineDefines.ERR_NO_ERROR) {
                Log.e(SpeechDemoDefines.TAG, "send directive start failed, " + ret);
            }
        }
        setTextOnUiThread(mResultTv, "");
    }

    private void stopEngineBtnClicked() {
        // Directive：关闭引擎，停止对话功能。
        Log.i(SpeechDemoDefines.TAG, "Directive: DIRECTIVE_STOP_ENGINE");
        mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_STOP_ENGINE, "");
    }

    private void startDialogBtnClicked() {
        configStartDialogParams();
        // Directive：关闭引擎内部播放功能。
        Log.i(SpeechDemoDefines.TAG, "Directive: DIRECTIVE_PLAYING_DECISION");
        mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_PLAYING_DECISION, "false");
        // Directive：开启对话指令，开启一轮对话。
        Log.i(SpeechDemoDefines.TAG, "Directive: DIRECTIVE_START_DIALOG");
        int ret = mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_START_DIALOG, "");
        if (ret != SpeechEngineDefines.ERR_NO_ERROR) {
            Log.e(SpeechDemoDefines.TAG, "send directive failed, " + ret);
        }
    }

    private void stopDialogBtnClicked() {
        // Directive：关闭对话指令，取消当前对话。
        Log.i(SpeechDemoDefines.TAG, "Directive: DIRECTIVE_CANCEL_CURRENT_DIALOG");
        mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_CANCEL_CURRENT_DIALOG, "");
    }

    private void recordBtnTouchDown() {
        recordIsRunning = false;
        recordHandler = new Handler();
        recordRunnable = () -> {
            Log.i(SpeechDemoDefines.TAG, "DialogTouch: Running");
            recordIsRunning = true;
            // Param：用户音频输入最大时长，单位毫秒。
            mSpeechEngine.setOptionInt(SpeechEngineDefines.PARAMS_KEY_VAD_MAX_SPEECH_DURATION_INT, 150000);
            // Directive：开启用户音频输入，对话过程中，可以通过该指令发送用户音频。
            Log.i(SpeechDemoDefines.TAG, "Directive: DIRECTIVE_START_TALKING");
            int ret = mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_START_TALKING, "");
            if (ret != SpeechEngineDefines.ERR_NO_ERROR) {
                Log.e(SpeechDemoDefines.TAG, "send directive failed, " + ret);
            }
        };
        recordHandler.postDelayed(recordRunnable, 500);
    }

    private void recordBtnTouchUp() {
        if (recordIsRunning) {
            recordIsRunning = false;
            Log.i(SpeechDemoDefines.TAG, "DialogTouch: Finish");
            // Directive：结束用户音频输入。
            Log.i(SpeechDemoDefines.TAG, "Directive: DIRECTIVE_FINISH_TALKING");
            mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_FINISH_TALKING, "");
        } else if (recordRunnable != null) {
            Log.i(SpeechDemoDefines.TAG, "DialogTouch: Cancel");
            recordHandler.removeCallbacks(recordRunnable);
            recordRunnable = null;
        }
    }

    @Override
    public void onSpeechMessage(int type, byte[] data, int len) {
        String stdData = new String(data);
        switch (type) {
            case SpeechEngineDefines.MESSAGE_TYPE_ENGINE_START:
                // Callback: 引擎启动成功回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 引擎启动成功: " + type);
                speechEngineStarted();
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_ENGINE_STOP:
                // Callback: 引擎关闭回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 引擎关闭: " + type);
                speechEngineStopped();
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_ENGINE_ERROR:
                // Callback: 错误信息回调
                Log.e(SpeechDemoDefines.TAG, "Callback: 错误信息: " + type + " data: " + stdData);
                speechEngineError(stdData);
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_DIALOG_BEGIN:
                // Callback: 对话开始回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 对话开始: " + type + " data: " + stdData);
                speechDialogStarted();
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_DIALOG_CHANNEL_JOINED:
                // Callback: 对话过程中，加入频道回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 对话过程中，加入频道回调: " + type);
                speechDialogChannelJoined();
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_DIALOG_SUBTITLE_ON:
                // Callback: 对话过程中，字幕信息回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 对话过程中，字幕信息回调: " + type + " data: " + stdData);
                speechDialogSubtitleOn(stdData);
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_DIALOG_SUBTITLE_OFF:
                // Callback: 对话过程中，字幕结束信息回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 对话过程中，字幕结束信息回调: " + type);
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_DIALOG_VOICE_BEGIN:
                // Callback: 对话过程中，播报开始回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 对话过程中，播报开始回调: " + type);
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_DIALOG_VOICE_END:
                // Callback: 对话过程中，播报结束回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 对话过程中，播报结束回调: " + type);
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_VAD_BEGIN:
                // Callback: 对话过程中，用户开始说话回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 对话过程中，用户开始说话回调: " + type);
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_PARTIAL_RESULT:
                // Callback: 对话过程中，用户语音识别结果回调
                Log.d(SpeechDemoDefines.TAG, "Callback: 对话过程中，用户语音识别结果回调: " + type + " data: " + stdData);
                speechAsrPartialResult(stdData);
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_VAD_END:
                // Callback: 对话过程中，用户说话结束回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 对话过程中，用户说话结束回调: " + type);
                break;
            case SpeechEngineDefines.MESSAGE_TYPE_DIALOG_END:
                // Callback: 对话结束回调
                Log.i(SpeechDemoDefines.TAG, "Callback: 对话结束: " + type + " data: " + stdData);
                speechDialogStopped();
                break;
            default:
                break;
        }
    }

    public void speechEnginInitOk() {
        Log.i(SpeechDemoDefines.TAG, "引擎初始化成功!");
        this.runOnUiThread(() -> {
            mEngineStatusTv.setText(R.string.hint_ready);
            setButton(mInitEngineBtn, false);
            setButton(mUninitEngineBtn, true);
            setButton(mStartEngineBtn, true);
            setButton(mStartDialogBtn, false);
            setButton(mStopDialogBtn, false);
            setButton(mRecordBtn, false);
        });
    }

    public void speechEngineInitFailed(String tipText) {
        Log.e(SpeechDemoDefines.TAG, "引擎初始化失败: " + tipText);
        this.runOnUiThread(() -> {
            mEngineStatusTv.setText(R.string.hint_setup_failure);
            setButton(mInitEngineBtn, true);
            setResultText(tipText);
        });
    }

    public void speechEngineStarted() {
        mEngineStarted = true;
        this.runOnUiThread(() -> {
            mEngineStatusTv.setText(R.string.hint_start_cb);
            setButton(mStartEngineBtn, false);
            setButton(mStopEngineBtn, true);
            setButton(mStartDialogBtn, true);
            setButton(mStopDialogBtn, false);
        });
    }

    public void speechEngineStopped() {
        mEngineStarted = false;
        this.runOnUiThread(() -> {
            mEngineStatusTv.setText(R.string.hint_stop_cb);
            setButton(mStartEngineBtn, true);
            setButton(mStopEngineBtn, false);
            setButton(mStartDialogBtn, false);
            setButton(mStopDialogBtn, false);
        });
    }

    public void speechEngineError(final String data) {
        this.runOnUiThread(() -> {
            try {
                JSONObject reader = new JSONObject(data);
                if (!reader.has("err_code") || !reader.has("err_msg")) {
                    return;
                }
                setResultText(data);
                stopEngineBtnClicked();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        });
    }

    public void speechDialogStarted() {
        this.runOnUiThread(() -> mEngineStatusTv.setText(R.string.hint_dialog_start_cb));
    }

    public void speechDialogChannelJoined() {
        this.runOnUiThread(() -> {
            mEngineStatusTv.setText(R.string.hint_dialog_join_cb);
            setButton(mStartDialogBtn, false);
            setButton(mStopDialogBtn, true);
            setButton(mRecordBtn, true);
        });
    }

    public void speechDialogSubtitleOn(final String data) {
        this.runOnUiThread(() -> {
            try {
                JSONObject reader = new JSONObject(data);
                if (!reader.has("data")) {
                    return;
                }
                String text = "Bot: " + reader.getJSONObject("data").getString("text").trim();
                setResultText(text);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        });
    }

    public void speechAsrPartialResult(final String data) {
        this.runOnUiThread(() -> {
            try {
                JSONObject reader = new JSONObject(data);
                if (!reader.has("data")) {
                    return;
                }
                String result = reader.getJSONObject("data").getString("text").trim();
                if (!result.isEmpty()) {
                    String text = "User: " + result;
                    setResultText(text);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        });
    }

    public void speechDialogStopped() {
        this.runOnUiThread(() -> {
            mEngineStatusTv.setText(R.string.hint_dialog_stop_cb);
            setButton(mStartDialogBtn, true);
            setButton(mStopDialogBtn, false);
            setButton(mRecordBtn, false);
        });
    }

    public void setResultText(final String text) {
        if (mResultTv.getText().equals("")) {
            mResultTv.setText(text);
        } else {
            mResultTv.append("\n" + text);
        }
    }

}